package com.liuxinlong.modules.system.service.impl;

import cn.hutool.core.io.FileUtil;
import com.liuxinlong.common.AosException;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.FileBusinessTypeEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.BackupDao;
import com.liuxinlong.modules.dao.FileManageDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.entity.Backup;
import com.liuxinlong.modules.entity.FileManage;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.system.dto.BackupDto;
import com.liuxinlong.modules.system.service.BackupService;
import com.liuxinlong.utils.FileUtils;
import com.liuxinlong.utils.MysqlDataBackupUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 数据备份记录实现类
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022-07-19
 */
@Service
@Slf4j
public class BackupServiceImpl implements BackupService {
    @Autowired
    private BackupDao backupDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private FileManageDao fileManageDao;

    public static final String BACKUP_DEST = "/data";

    @Override
    public List<Map<String, Object>> pageBackupInfo(Map<String, Object> queryParam) {
        List<BackupDto> originList = backupDao.pageBackupList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        if (ObjectUtils.isEmpty(originList)) {
            return resultList;
        }
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        int sort = (int) queryParam.get("startNum") + 1;
        for (BackupDto backup : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(backup);
            map.put("sort", sort);
            if (!StringUtils.isEmpty(backup.getOperateUser())) {
                map.put("userName", userMap.containsKey(backup.getOperateUser()) ? userMap.get(backup.getOperateUser()).get("name") : "");
            }
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    @Override
    public int countBackupInfo(Map<String, Object> queryParam) {
        return backupDao.getBackupCount(queryParam);
    }

    @Override
    public void createInfo(String backupId, String fileId, String backupPath, int type) {
        File file = new File(BACKUP_DEST);
        // 如果文件目录不存在，就执行创建
        if (!file.isDirectory()) {
            file.mkdirs();
        }
        String startTime = TimeUtils.getDate(TimeFormatConstants.YYYYMMDDHHMMSS);
        Backup backup = new Backup();
        backup.setId(backupId);
        backup.setBusinessType(2);
        backup.setBusinessId(backupId);
        backup.setFileId(fileId);
        backup.setStartTime(startTime);
        backup.setOperateTime(startTime);
        backup.setStatus(1);
        backupDao.insert(backup);

        FileManage fileManage = new FileManage();
        fileManage.setId(fileId);
        fileManage.setFileType(type == 1 ? "sql" : "zip");
        fileManage.setBusinessType(FileBusinessTypeEnum.BACKUP_FILE.getValue());
        fileManage.setBusinessId(backupId);
        fileManage.setFilePath(BACKUP_DEST + backupPath);
        fileManage.setName("备份文件" + startTime);
        fileManage.setOperateTime(startTime);
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        fileManage.setOperateUser(ObjectUtils.isEmpty(currentUser) ? "系统" : currentUser.getId());
        fileManageDao.insert(fileManage);
    }

    @Override
    public void deleteBackup(String id) {

    }

    @Override
    public void exportBackup(HttpServletResponse response) {
        MysqlDataBackupUtils.backupAll("/sql/pmip_2022.sql");
//        String exportPath = savePath + exportDatabaseName +"_"+ DateUtil.formatDate_1(new Date()) + ".sql";
    }

    @Override
    @Transactional
    @Async
    public void startBackup(String backupId, String fileId, String backupPath, int type) {
        boolean isSuccess = false;
        if (type == 1) {
            isSuccess = MysqlDataBackupUtils.backupAll(BACKUP_DEST + backupPath);
        } else if (type == 2) {
            backupPath = BACKUP_DEST + "/fileBackup" + fileId + ".zip";
            String filePath = BACKUP_DEST + "/fileBackup";
            FileUtils.copyDir("upload/", filePath + "/upload/");
            FileUtils.copyDir("uploadCHIMI/", filePath + "/uploadCHIMI/");
//            FileUtils.copyDir("uploadLocal/", filePath + "/uploadLocal/");
//            FileUtils.copyDir("uploadProject/", filePath + "/uploadProject/");
//            FileUtils.copyDir("uploadSpo/", filePath + "/uploadSpo/");
//            FileUtils.copyDir("uploadTemp/", filePath + "/uploadTemp/");
            isSuccess = FileUtils.packageZip(filePath, backupPath);
            if (isSuccess) {
                isSuccess = FileUtil.del(filePath);
            }
        } else {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR);
        }
        String endTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        backupDao.updateStatus(backupId, isSuccess ? 2 : 3, endTime);
    }

//    private List<String> backupFile(List<String> pathList) {
//
//    }
}
